package com.gomcarter.frameworks.base.converter.enums;

import com.gomcarter.frameworks.base.exception.CustomException;
import org.springframework.util.Assert;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by daibing on 2024/1/29.
 */
public class EnumConverterManager {
    /**
     * 缓存枚举类对应的解析静态方法
     */
    private static final ConcurrentMap<String, Method> TARGET_2_METHOD = new ConcurrentHashMap<>();

    public static Class<?> getEnumType(Class<?> targetType) {
        Class<?> enumType = targetType;
        while (enumType != null && !enumType.isEnum()) {
            enumType = enumType.getSuperclass();
        }
        Assert.notNull(enumType, () -> "The target type " + targetType.getName() + " does not refer to an enum");
        return enumType;
    }

    public static Method getDeclaredMethod(Class<?> enumType, String enumResolverMethodName) throws NoSuchMethodException {
        String key = enumType.getName() + "." + enumResolverMethodName;
        Method method = TARGET_2_METHOD.get(key);
        if (method != null) {
            return method;
        }
        synchronized (TARGET_2_METHOD) {
            method = TARGET_2_METHOD.get(key);
            if (method != null) {
                return method;
            }
            try {
                TARGET_2_METHOD.put(key, enumType.getDeclaredMethod(enumResolverMethodName, String.class));
            } catch (NoSuchMethodException e) {
                TARGET_2_METHOD.put(key, enumType.getDeclaredMethod(enumResolverMethodName, Integer.class));
            }
        }
        return TARGET_2_METHOD.get(key);
    }

    public static boolean argIsNumber(Class<?> enumType, String enumResolverMethodName) {
        String key = enumType.getName() + "." + enumResolverMethodName;
        Method method = Optional
                .ofNullable(TARGET_2_METHOD.get(key))
                .orElseThrow(() -> new CustomException(enumType.getName() + "未匹配到转换Enum的自定义静态方法：" + enumResolverMethodName));
        Class<?>[] parameterTypes = method.getParameterTypes();
        return Arrays.stream(parameterTypes).allMatch(s -> s == Integer.class);
    }

}
